demo-app/pages/product/[productId].js (102 lines of code) (raw):

import React from "react"; import { Form, Field } from "react-final-form"; import useSWR from "swr"; import Cookies from "js-cookie"; import Header from "../../components/Header"; import Footer from "../../components/Footer"; import Price from "../../components/Price"; import Recommendations from "../../components/Recommendations"; import Ad from "../../components/Ad"; import * as storage from "../../utils/storage"; export async function getServerSideProps({ params }) { return { props: { productId: params.productId, }, }; } const onSubmit = async (value) => { const sessionId = Cookies.get("session_id"); if (!storage.get(sessionId)) { storage.set(sessionId, []); } const { productId, quantity } = value; const items = storage.get(sessionId); items.push({ id: productId, quantity }); storage.set(sessionId, items); window.location.replace("/cart"); }; const ProductForm = ({ data }) => ( <Form onSubmit={onSubmit} initialValues={{ productId: data.id, quantity: 1 }} render={({ handleSubmit, form }) => ( <form onSubmit={handleSubmit} className="form-inline text-muted"> <> <Field name="productId" component="input" type="hidden" /> </> <div className="input-group"> <div className="input-group-prepend"> <label className="input-group-text" htmlFor="quantity"> Quantity </label> <Field name="quantity" component="select" className="custom-select form-control form-control-lg" > <option value="1">1</option> <option value="2">2</option> <option value="3">3</option> <option value="4">4</option> <option value="5">5</option> </Field> </div> <button type="submit" className="btn btn-info btn-lg ml-3"> Add to Cart </button> </div> </form> )} /> ); const Product = ({ productId }) => { const { data, error } = useSWR(`/api/product/${productId}`, (url) => fetch(url).then((r) => r.json()) ); if (error) return <div>Failed to load products</div>; if (!data) return <div>loading products...</div>; const { product, recommendations, ads } = data; return ( <> <Header /> <main role="main"> <div className="py-5"> <div className="container bg-light py-3 px-lg-5 py-lg-5"> <div className="row"> <div className="col-12 col-lg-5"> <img className="img-fluid border" src={product.picture} /> </div> <div className="col-12 col-lg-7"> <h2>{product.name}</h2> <Price data={product} /> <hr /> <h6>Product Description: {product.description}</h6> <hr /> <ProductForm data={product} /> </div> </div> {recommendations && recommendations.length > 0 && ( <Recommendations recommendations={recommendations} /> )} {ads && <Ad data={ads} />} </div> </div> <style jsx>{` .img-fluid border { width: 100%; } `}</style> </main> <Footer /> </> ); }; export default Product;